package models

import (
	"fmt"
	"qld2devservice/utils"
	"time"
)

type QldOutlet struct {
	Id           int `gorm:"primary_key"`
	AddBy        int64
	AddDate      time.Time
	Address      string //地址
	AreaId       int64
	Current      int
	ExtraId      int64
	Img          string
	IsWorking    int8 //0:未工作 1:工作中
	Lat          float64
	Lng          float64
	Name         string
	OutletInfo   string
	PriceId      int64
	PriceInnerId int64
	SnNum        string
	Status       int8
	Type         int8
	ProtocolId   int64
	ControlId    int64
	UserId       int64 //正在使用的用户id
	Voltage      int
}

func GetAllQldOutlet() ([]QldOutlet, error) {
	var qldOutlets []QldOutlet
	//条件查询
	err := DB.Find(&qldOutlets).Error
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, err.Error())
	}
	return qldOutlets, nil
}

func GetAllQldOutletSnNumAndTypeAndStatus() ([]QldOutlet, error) {
	var qldOutlets []QldOutlet
	//条件查询
	err := DB.Select("sn_num, type, status").Find(&qldOutlets).Error
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, err.Error())
	}
	return qldOutlets, nil
}

func GetAllQldOutletSnNumAndIsWorkingAndStatus() ([]QldOutlet, error) {
	var qldOutlets []QldOutlet
	//条件查询
	err := DB.Select("sn_num, is_working, status").Find(&qldOutlets).Error
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, err.Error())
	}
	return qldOutlets, nil
}

func GetQldOutletsBySnNum(snNum string) ([]QldOutlet, error) {
	var qldOutlets []QldOutlet
	//条件查询
	err := DB.Where("sn_num = ?", snNum).Find(&qldOutlets).Error
	if err != nil {
		newErr := utils.WrapError(err, "GetQldOutletsBySnNum:1,数据库获取设备失败,snNum="+snNum)
		utils.MyPrint(utils.PRINT_ERROR, newErr.Error())
		return []QldOutlet{}, newErr
	}
	return qldOutlets, nil
}

//func GetQldOutletBySnNum(snNum string) (QldOutlet, error) {
//	var qldOutlets []QldOutlet
//	//条件查询
//	err := DB.Where("sn_num = ?", snNum).Find(&qldOutlets).Error
//	if err != nil {
//		newErr := utils.WrapError(err, "GetQldOutletBySnNum:1,数据库获取设备失败,snNum="+snNum)
//		utils.MyPrint(utils.PRINT_ERROR ,newErr.Error())
//		return QldOutlet{}, newErr
//	} else if len(qldOutlets) == 0 {
//		newErr := utils.NewError(utils.ErrorTypeStop, "GetQldOutletBySnNum:2,数据库获取设备未获取到,snNum="+snNum)
//		utils.MyPrint(utils.PRINT_ERROR ,newErr.Error())
//		return QldOutlet{}, newErr
//	} else if len(qldOutlets) > 1 {
//		newErr := utils.WrapError(err, "GetQldOutletBySnNum:3,数据库获取设备获取到多个,"+fmt.Sprintf("%+v", qldOutlets))
//		utils.MyPrint(utils.PRINT_ERROR ,newErr.Error())
//		return qldOutlets[0], newErr
//	}
//	return qldOutlets[0], nil
//}

func SetQldOutletValue(snNum string, isWorking int8, userId int64) (err error) {
	//条件查询
	var qldOutlet QldOutlet
	err = DB.Model(&qldOutlet).Where("sn_num = ?", snNum).Update(map[string]interface{}{"is_working": isWorking, "user_id": userId}).Error
	if err != nil {
		newErr := utils.WrapError(err, "SetQldOutletValue:1,数据库设备信息更新失败,"+snNum)
		utils.MyPrint(utils.PRINT_ERROR, newErr.Error())
		return newErr
	}
	return nil
}

func SetQldOutleStatus(snNum string, Status int8) (qldOutlet QldOutlet, err error) {
	utils.MyPrint(utils.PRINT_INFO, "qldOutlet QldOutlet %s %d \n", snNum, Status)
	err = DB.Model(&qldOutlet).Where("sn_num = ?", snNum).Update("status", Status).Error
	if err != nil {
		newErr := utils.WrapError(err, "SetQldOutleStatus:1,数据库设备信息更新失败,"+snNum)
		utils.MyPrint(utils.PRINT_ERROR, newErr.Error())
		return QldOutlet{}, newErr
	}
	utils.MyPrint(utils.PRINT_INFO, "SetQldOutleStatus 处理故障")
	return
}

func SetQldOutleStatusBySnNumList(snNumList []string, status int8) (err error) {
	err = DB.Table("qld_outlet").Where("sn_num IN (?) and status<> 1", snNumList).Updates(map[string]interface{}{"status": status}).Error
	if err != nil {
		newErr := utils.WrapError(err, "SetQldOutleStatusBySnNumList:数据库设备信息更新失败")
		utils.MyPrint(utils.PRINT_ERROR, newErr.Error())
		return newErr
	}
	utils.MyPrint(utils.PRINT_INFO, "SetQldOutleStatusBySnNumList 处理故障")
	return
}

// TODO ========以下是为了实时统计故障使用，后续改变了统计方式，暂未使用暂时保留代码 防止在使用======

func HandlingFault(snNumList []string, status int8) {

	utils.MyPrint(utils.PRINT_INFO, "进入 HandlingFault 处理故障")

	var qldOutlets []utils.QldOutlet
	fmt.Println("1111:", snNumList)
	err := DB.Debug().Select("id,area_id,sn_num,status,name").Where("sn_num IN (?)", snNumList).Find(&qldOutlets).Error
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "HandlingFault -1:", err.Error())
		return
	}

	if len(qldOutlets) == 0 {
		utils.MyPrint(utils.PRINT_ERROR, "HandlingFault qldOutlets num 0 -2")
		return
	}

	faultInfoList := make([]*QldOutletFaultInfo, 0)
	for _, outlet := range qldOutlets {
		faultInfo := &QldOutletFaultInfo{
			//Id:          0,
			AreaId:      outlet.AreaId,
			DeviceState: int(status),
			DeviceId:    outlet.Id,
			UpdateTime:  time.Now(),
			CreateTime:  time.Now(),
		}
		faultInfoList = append(faultInfoList, faultInfo)
	}

	err = BatchAddQldOutletFaultInfo(faultInfoList)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "HandlingFault -3:", err)
		return
	}

	if len(qldOutlets) > 0 {
		areaIdList := removeDuplicates(qldOutlets)
		utils.MyPrint(utils.PRINT_INFO, "HandlingFault 要执行修园区扩展表的数据是:", areaIdList)
		handlingAreaExt(areaIdList)
	}

	utils.MyPrint(utils.PRINT_INFO, "结束 HandlingFault 处理故障")
}

func handlingAreaExt(areaIdList []int64) {

	for _, areaId := range areaIdList {

		var outLetNum int64
		var outLetFaultNum int64
		// 获取设备数量
		err := DB.Model(&utils.QldOutlet{}).Where("area_id=?", areaId).Count(&outLetNum).Error
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, "handlingAreaExt -1:", err.Error())
			return
		}
		// 获取园区设备故障数量
		err = DB.Model(&utils.QldOutlet{}).Where("area_id=?", areaId).Where("status <> ?", 0).Count(&outLetFaultNum).Error
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, "handlingAreaExt -2:", err.Error())
			return
		}

		// 判断状态所属值
		var areaFaultState int
		if outLetFaultNum == outLetNum {
			areaFaultState = utils.FullFault.Int()
		} else if outLetFaultNum < outLetNum {
			areaFaultState = utils.PartialFault.Int()
		} else if outLetFaultNum == 0 {
			areaFaultState = utils.NoFault.Int()
		}

		areaExtInfo, err := GetQldOutletAreaExt(areaId)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, "handlingAreaExt -3:", err.Error())
			return
		}

		// 获取最新故障记录数据
		faultInfo, err := GetQldOutletFaultInfo(areaId)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, "handlingAreaExt -4:", err.Error())
			return
		}

		// 判断数据是否存在
		if areaExtInfo.Id == 0 {

			extInfo := &QldOutletAreaExt{
				Id:           0,
				AreaId:       areaId,
				DevopsStatus: 1,
				FaultStatus:  areaFaultState,
				FaultTime:    faultInfo.CreateTime,
				FaultSort:    1000,
			}

			_, err = AddQldOutletAreaExt(extInfo)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, "handlingAreaExt -5:", err.Error())
				return
			}

		} else {

			dataMap := make(map[string]interface{})
			dataMap["fault_status"] = areaFaultState
			dataMap["fault_time"] = faultInfo.CreateTime

			if areaExtInfo.FaultSort == 0 {
				dataMap["fault_sort"] = 1000
			}

			_, err = UpdateQldOutletAreaExt(areaId, dataMap)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, "handlingAreaExt -6:", err.Error())
				return
			}

		}

	}

}

func removeDuplicates(outlets []utils.QldOutlet) []int64 {
	seen := make(map[int64]bool)
	var result []int64
	for _, outlet := range outlets {
		if !seen[outlet.AreaId] {
			result = append(result, outlet.AreaId)
			seen[outlet.AreaId] = true
		}
	}

	return result
}

// TODO ======================== 故障统计区域代码  结束==============================================
